/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package service

import (
	"icep/bean/entity"
	"icep/bean/model"
	"icep/bean/param"
	"icep/common/constant"
	"icep/common/crypto/gm"
	"icep/common/cryptoprovider"
	"icep/common/db"
	"icep/common/utils"
	"icep/common/uuid"
	"time"

	"github.com/pkg/errors"
)

func (is *IcepService) QueryUserList(userType, phone, mail, status string, pageSize, pageNo int) *db.Page {
	args := make([]interface{}, 0)
	condition := "user_type != '0'"
	if userType != "" {
		condition = utils.StrJoin(condition, "  and user_type = ? ")
		args = append(args, userType)
	}

	if phone != "" {
		condition = utils.StrJoin(condition, " and phone = ? ")
		args = append(args, phone)
	}

	if mail != "" {
		condition = utils.StrJoin(condition, " and mail = ? ")
		args = append(args, mail)
	}

	if status != "" {
		condition = utils.StrJoin(condition, " and status = ? ")
		args = append(args, status)
	}
	page := db.NewPage(0, pageNo).SetPageSize(pageSize)

	var countEntity entity.IcepUser
	count, err := is.DbEngine.Where(condition, args...).Count(&countEntity)
	if err != nil {
		log.Errorf("query user list count error: %s", err)
		return nil
	}
	page.SetTotal(count)

	userList := make([]*entity.IcepUser, 0)
	err = is.DbEngine.Where(condition, args...).Limit(pageSize, (pageNo-1)*pageSize).Desc("updated_time").Find(&userList)
	if err != nil {
		log.Errorf("query user list error: %s", err)
		return nil
	}
	userDetailList := make([]*model.UserDetail, 0)
	for _, user := range userList {
		userDetailList = append(userDetailList, &model.UserDetail{
			Id:          user.Id,
			TenantId:    user.TenantId,
			UserType:    user.UserType,
			Phone:       user.Phone,
			Mail:        user.Mail,
			Status:      user.Status,
			CreatedTime: user.CreatedTime.Format(constant.TimeLayout),
			UpdatedTime: user.UpdatedTime.Format(constant.TimeLayout),
		})
	}
	//稳定排序
	//sort.SliceStable(userDetailList, func(i, j int) bool { return userDetailList[i].UpdatedTime > userDetailList[j].UpdatedTime })
	page.CreatePage(userDetailList)
	return page
}

func (is *IcepService) CreateUser(userParam param.CreateUserParam) error {
	user := make([]*entity.IcepUser, 0)
	err := is.DbEngine.Where("phone = ? or mail = ?", userParam.Phone, userParam.Mail).Find(&user)
	if err != nil {
		return errors.Errorf("query before create user error: %s", err)
	}
	if len(user) > 0 {
		for _, user := range user {
			if userParam.Phone == user.Phone {
				return errors.New("手机号已存在！")
			}
			return errors.New("邮箱已存在！")
		}
	}
	//password := sha256.Sha256(userParam.Password + config.Get("icep.salt", constant.DefaultSalt))
	password := cryptoprovider.Get().Encrypt(userParam.Password)
	prvKeyHex, pubKeyHex, _ := gm.GenerateSM2Keys()
	sm4EcpPrvKey := gm.EncryptPrvKey(prvKeyHex)
	now := time.Now()
	userEntity := entity.IcepUser{
		Id:          uuid.Generate(),
		TenantId:    userParam.TenantId,
		UserType:    userParam.UserType,
		Phone:       userParam.Phone,
		Mail:        userParam.Mail,
		Password:    password,
		PrvKey:      sm4EcpPrvKey,
		PubKey:      pubKeyHex,
		Status:      constant.UserStatusNormal,
		CreatedTime: now,
		UpdatedTime: now,
	}
	_, err = is.DbEngine.InsertOne(userEntity)
	if err != nil {
		return errors.Errorf("insert user error: %s", err)
	}

	return nil
}

func (is *IcepService) PutUser(userParam param.PutUserParam) error {
	user := make([]*entity.IcepUser, 0)
	err := is.DbEngine.Where("id  = ?", userParam.Id).Find(&user)

	if err != nil {
		return errors.Errorf("query before update user error: %s", err)
	}
	if len(user) == 0 {
		return errors.New("用户不存在！")
	}

	//password := sha256.Sha256(userParam.Password + config.Get("icep.salt", constant.DefaultSalt))
	password := cryptoprovider.Get().Encrypt(userParam.Password)
	now := time.Now()
	userEntity := entity.IcepUser{
		Password:    password,
		UpdatedTime: now,
	}

	_, err = is.DbEngine.Where("id  = ?", userParam.Id).Update(userEntity)
	if err != nil {
		return errors.Errorf("update user error: %s", err)
	}

	return nil
}
